import { sendDataToPeers } from '@/utils/peer'
import { Canvas, PencilBrush, Point, util } from 'fabric'

export let canvas: Canvas
export let pencilBrush: PencilBrush
export const setCanvas = (value: Canvas) => {
  canvas = value
}

export function jsonAddToBoard(json: any) {
  util.enlivenObjects(json).then((objects) => {
    objects.forEach(function (o: any) {
      canvas.add(o)
    })
  })
}

export function removeBoardObject(data: any) {
  const removeObject = canvas.getObjects().find((o: any) => o.id === data)
  removeObject && canvas.remove(removeObject)
}

export function getBoardObjectsJson() {
  return canvas?.getObjects()?.map((o: any) => ({ ...o.toJSON(), id: o.id }))
}

// export function saveBoard() {
//   const objects = canvas.getObjects()
//   request('board-change', {
//     pathname: roomName,
//     boardPaths: objects.map((o: any) => ({ ...o.toJSON(), id: o.id })),
//   })
// }
export function initBoardCanvas(canvasEl: HTMLCanvasElement) {
  // 设置canvas的触摸样式
  canvasEl.style.touchAction = 'none'

  canvas = new Canvas(canvasEl, {
    isDrawingMode: true,
    stopContextMenu: true,
    fireMiddleClick: true,
    fireRightClick: true,
    allowTouchScrolling: false,
    selection: false,
    // 禁用fabric.js的触摸事件
    enableRetinaScaling: false,
  })
  pencilBrush = new PencilBrush(canvas)
  pencilBrush.color = 'red'
  pencilBrush.width = 10
  canvas.freeDrawingBrush = pencilBrush

  canvas.on('path:created', function (e: any) {
    // console.log("path:created", e);
    const newPath = e.path
    const id = crypto.randomUUID()
    e.path.set({ id })

    const json = newPath.toJSON()
    sendDataToPeers({ type: 'board-object-add', data: { ...json, id } })
    // saveBoard()
  })
  canvas.on('mouse:wheel', (opt) => {
    opt.e.preventDefault()
    opt.e.stopPropagation()

    if (opt.e.ctrlKey) {
      console.log('pinch')
      const delta = opt.e.deltaY
      let zoom = canvas.getZoom()
      zoom *= 0.999 ** delta
      canvas.setZoom(zoom)
    } else {
      // const e = opt.e
      // const vpt = canvas.viewportTransform
      // vpt[4] += e.deltaX
      // vpt[5] += e.deltaY
      // canvas.requestRenderAll()
      const delta = opt.e.deltaY // 滚轮，向上滚一下是 -100，向下滚一下是 100
      let zoom = canvas.getZoom() // 获取画布当前缩放值
      zoom *= 0.996 ** delta
      if (zoom > 20) zoom = 20 // 限制最大缩放级别
      if (zoom < 0.01) zoom = 0.01 // 限制最小缩放级别

      // 以鼠标所在位置为原点缩放
      const point = new Point(opt.e.offsetX, opt.e.offsetY)
      canvas.zoomToPoint(
        point,
        zoom, // 传入修改后的缩放级别
      )
    }
  })
  // canvas拖拽
  let mouseDownButton: number | null = null
  canvas.on('mouse:up', () => {
    // console.log("mouse:up", e);
    mouseDownButton = null
  })
  canvas.on('mouse:down', (e: any) => {
    // console.log('mouse:down', e.e.button)
    // if (e.e.button === 1) {
    //   isMiddleMouseDown = true
    // }
    mouseDownButton = e.e.button
    if (e.e.button === 2 && e.target) {
      // console.log(e.target, canvas.getObjects());
      canvas.remove(e.target)
      sendDataToPeers({ type: 'board-object-remove', data: e.target.id })
      // saveBoard()
    }
  })
  canvas.on('mouse:move', (e) => {
    // console.log("mouse:move", e);
    const event: any = e?.e
    if (mouseDownButton && event) {
      const point = new Point(event.movementX, event.movementY)
      canvas.relativePan(point)
    }
  })

  // 移动端多指触摸支持
  let lastTouchDistance = 0
  let lastTouchCenter = { x: 0, y: 0 }
  let isTwoFinger = false
  let isThreeFinger = false

  // 计算两点之间的距离
  function getTouchDistance(touch1: Touch, touch2: Touch) {
    const dx = touch1.clientX - touch2.clientX
    const dy = touch1.clientY - touch2.clientY
    return Math.sqrt(dx * dx + dy * dy)
  }

  // 计算两点的中心点
  function getTouchCenter(touch1: Touch, touch2: Touch) {
    return {
      x: (touch1.clientX + touch2.clientX) / 2,
      y: (touch1.clientY + touch2.clientY) / 2,
    }
  }

  canvasEl.addEventListener(
    'touchstart',
    (e) => {
      console.log('touchstart', e.touches.length)
      if (e.touches.length === 2) {
        e.preventDefault()
        e.stopPropagation()
        isTwoFinger = true
        isThreeFinger = false
        canvas.isDrawingMode = false // 禁用绘图模式

        const touch1 = e.touches[0]
        const touch2 = e.touches[1]

        lastTouchDistance = getTouchDistance(touch1, touch2)
        lastTouchCenter = getTouchCenter(touch1, touch2)
        console.log('双指开始（仅缩放）', lastTouchDistance, lastTouchCenter)
      } else if (e.touches.length === 3) {
        e.preventDefault()
        e.stopPropagation()
        isTwoFinger = false
        isThreeFinger = true
        canvas.isDrawingMode = false // 禁用绘图模式

        // 使用三指的中心点
        const touch1 = e.touches[0]
        const touch2 = e.touches[1]
        const touch3 = e.touches[2]

        lastTouchCenter = {
          x: (touch1.clientX + touch2.clientX + touch3.clientX) / 3,
          y: (touch1.clientY + touch2.clientY + touch3.clientY) / 3,
        }
        console.log('三指开始（仅拖拽）', lastTouchCenter)
      } else {
        isTwoFinger = false
        isThreeFinger = false
        canvas.isDrawingMode = true // 恢复绘图模式
      }
    },
    { passive: false },
  )

  canvasEl.addEventListener(
    'touchmove',
    (e) => {
      if (e.touches.length === 2 && isTwoFinger) {
        e.preventDefault()
        e.stopPropagation()
        console.log('双指移动（缩放）')

        const touch1 = e.touches[0]
        const touch2 = e.touches[1]

        const currentDistance = getTouchDistance(touch1, touch2)
        const currentCenter = getTouchCenter(touch1, touch2)

        // 双指缩放
        if (lastTouchDistance > 0) {
          const scaleRatio = currentDistance / lastTouchDistance
          let zoom = canvas.getZoom() * scaleRatio

          // 限制缩放范围
          if (zoom > 20) zoom = 20
          if (zoom < 0.01) zoom = 0.01

          // 获取画布边界矩形
          const rect = canvasEl.getBoundingClientRect()
          // 以双指中心点为缩放原点
          const point = new Point(
            currentCenter.x - rect.left,
            currentCenter.y - rect.top,
          )
          canvas.zoomToPoint(point, zoom)
          console.log('缩放', zoom)
        }

        lastTouchDistance = currentDistance
        lastTouchCenter = currentCenter
      } else if (e.touches.length === 3 && isThreeFinger) {
        e.preventDefault()
        e.stopPropagation()
        console.log('三指移动（拖拽）')

        // 计算三指的中心点
        const touch1 = e.touches[0]
        const touch2 = e.touches[1]
        const touch3 = e.touches[2]

        const currentCenter = {
          x: (touch1.clientX + touch2.clientX + touch3.clientX) / 3,
          y: (touch1.clientY + touch2.clientY + touch3.clientY) / 3,
        }

        // 三指拖拽（平移）
        if (lastTouchCenter.x !== 0 && lastTouchCenter.y !== 0) {
          const deltaX = currentCenter.x - lastTouchCenter.x
          const deltaY = currentCenter.y - lastTouchCenter.y

          const point = new Point(deltaX, deltaY)
          canvas.relativePan(point)
          console.log('平移', deltaX, deltaY)
        }

        lastTouchCenter = currentCenter
      }
    },
    { passive: false },
  )

  canvasEl.addEventListener(
    'touchend',
    (e) => {
      console.log('touchend', e.touches.length)
      if (e.touches.length < 2) {
        isTwoFinger = false
        isThreeFinger = false
        lastTouchDistance = 0
        lastTouchCenter = { x: 0, y: 0 }
        canvas.isDrawingMode = true // 恢复绘图模式
      } else if (e.touches.length === 2) {
        // 从三指变为双指，切换到缩放模式
        isThreeFinger = false
        isTwoFinger = true
        const touch1 = e.touches[0]
        const touch2 = e.touches[1]
        lastTouchDistance = getTouchDistance(touch1, touch2)
        lastTouchCenter = getTouchCenter(touch1, touch2)
        console.log('切换到双指缩放模式')
      }
    },
    { passive: false },
  )

  // 额外在document上监听，防止事件被fabric.js拦截
  function isOverCanvas(touch: Touch) {
    const rect = canvasEl.getBoundingClientRect()
    return (
      touch.clientX >= rect.left &&
      touch.clientX <= rect.right &&
      touch.clientY >= rect.top &&
      touch.clientY <= rect.bottom
    )
  }

  document.addEventListener(
    'touchstart',
    (e) => {
      console.log('document touchstart', e.touches.length)
      if (e.touches.length >= 1 && isOverCanvas(e.touches[0])) {
        if (e.touches.length === 2) {
          e.preventDefault()
          e.stopPropagation()
          console.log('document 双指开始（缩放）')
          isTwoFinger = true
          isThreeFinger = false
          canvas.isDrawingMode = false

          const touch1 = e.touches[0]
          const touch2 = e.touches[1]

          lastTouchDistance = getTouchDistance(touch1, touch2)
          lastTouchCenter = getTouchCenter(touch1, touch2)
        } else if (e.touches.length === 3) {
          e.preventDefault()
          e.stopPropagation()
          console.log('document 三指开始（拖拽）')
          isTwoFinger = false
          isThreeFinger = true
          canvas.isDrawingMode = false

          const touch1 = e.touches[0]
          const touch2 = e.touches[1]
          const touch3 = e.touches[2]

          lastTouchCenter = {
            x: (touch1.clientX + touch2.clientX + touch3.clientX) / 3,
            y: (touch1.clientY + touch2.clientY + touch3.clientY) / 3,
          }
        }
      }
    },
    { passive: false },
  )

  document.addEventListener(
    'touchmove',
    (e) => {
      if (e.touches.length === 2 && isTwoFinger) {
        e.preventDefault()
        e.stopPropagation()
        console.log('document 双指移动（缩放）')

        const touch1 = e.touches[0]
        const touch2 = e.touches[1]

        const currentDistance = getTouchDistance(touch1, touch2)
        const currentCenter = getTouchCenter(touch1, touch2)

        if (lastTouchDistance > 0) {
          const scaleRatio = currentDistance / lastTouchDistance
          let zoom = canvas.getZoom() * scaleRatio

          if (zoom > 20) zoom = 20
          if (zoom < 0.01) zoom = 0.01

          const rect = canvasEl.getBoundingClientRect()
          const point = new Point(
            currentCenter.x - rect.left,
            currentCenter.y - rect.top,
          )
          canvas.zoomToPoint(point, zoom)
        }

        lastTouchDistance = currentDistance
        lastTouchCenter = currentCenter
      } else if (e.touches.length === 3 && isThreeFinger) {
        e.preventDefault()
        e.stopPropagation()
        console.log('document 三指移动（拖拽）')

        const touch1 = e.touches[0]
        const touch2 = e.touches[1]
        const touch3 = e.touches[2]

        const currentCenter = {
          x: (touch1.clientX + touch2.clientX + touch3.clientX) / 3,
          y: (touch1.clientY + touch2.clientY + touch3.clientY) / 3,
        }

        if (lastTouchCenter.x !== 0 && lastTouchCenter.y !== 0) {
          const deltaX = currentCenter.x - lastTouchCenter.x
          const deltaY = currentCenter.y - lastTouchCenter.y

          const point = new Point(deltaX, deltaY)
          canvas.relativePan(point)
        }

        lastTouchCenter = currentCenter
      }
    },
    { passive: false },
  )
}

export function clearBoard() {
  canvas.clear()
  // saveBoard()
}
